package com.cskaoyan.wordmemorize.common;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.StringUtils;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.ExcelParseException;
import com.cskaoyan.wordmemorize.dao.mapper.VocBookMapper;
import com.cskaoyan.wordmemorize.dao.mapper.VocChapterMapper;
import com.cskaoyan.wordmemorize.dto.admin.VocExcelDTO;
import com.cskaoyan.wordmemorize.service.VocService;
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
@Slf4j
// 有个很重要的点 DemoDataListener 不能被spring管理，要每次读取excel都要new,然后里面用到spring可以构造方法传进去
public class MyHeaderReadListener extends AnalysisEventListener<VocExcelDTO> {
    private static final Map<Integer, String> EXPECTED_HEADERS = Map.of(
            0, "单词",
            1, "英式音标",
            2, "美式音标",
            3, "英式发音文件名",
            4, "美式发音文件名",
            5, "释义",
            6, "例句",
            7, "单词位置"
    );
    private int currentRow = 1; // 当前行号（从1开始，包含标题行）

    // 如果需要使用其他Mapper，或者Service的话，可以定义成员变量，以及对应的构造方法

    private VocBookMapper vocBookMapper;
    private VocChapterMapper vocChapterMapper;

    public MyHeaderReadListener(VocBookMapper vocBookMapper,VocChapterMapper vocChapterMapper) {
        this.vocBookMapper = vocBookMapper;
        this.vocChapterMapper = vocChapterMapper;
    }
    // 我们只需要重写invokeHeadMap方法即可获取Excel文件头
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        if (headMap.size() != EXPECTED_HEADERS.size()) {
            throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_FORMAT_ERROR,"Excel文件头格式错误");
        }
        EXPECTED_HEADERS.forEach((index, expectedHeader) -> {
            String actualHeader = headMap.get(index);
            if (!expectedHeader.equals(actualHeader)) {
                throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_FORMAT_ERROR,String.format("第%d列表头不匹配，预期: '%s'，实际: '%s'",
                        index + 1, expectedHeader, actualHeader));
            }
        });
    }

    // 该方法就是ReadListener父接口中定义的方法，用来读取行数据
    @Override
    public void invoke(VocExcelDTO data, AnalysisContext context) {
        currentRow++;
        if (StringUtils.isBlank(data.getContent())) {
            throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_PARSE_ERROR,"单词不能为空");
        }
        checkInterpretations(data.getInterpretations());
        checkExamples(data.getExampleSentences());
        checkBookInfo(data.getBookInfos());
    }

    // 该方法就是ReadListener父接口中定义的方法，在excel读取完毕后执行
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {

        log.info("Excel文件校验通过，共检查 {} 行数据", currentRow - 1);
    }

    private void checkInterpretations(String interpretations) {
        if (StringUtils.isBlank(interpretations)) {
            throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_DATA_ERROR,"释义不能为空");
        }

        String[] lines = interpretations.split("\n");
        for (int i = 0; i < lines.length; i++) {
            String line = lines[i].trim();
            if (line.isEmpty()) continue;

            // 检查释义格式是否为"词性.释义"
            int dotIndex = line.indexOf('.');
            if (dotIndex <= 0 || dotIndex == line.length() - 1 ||!Character.isLetter(line.charAt(0))) {
                throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_DATA_ERROR,String.format("第%d行释义格式错误",currentRow));
            }
        }
    }
    private void checkExamples(String examples) {
        if (StringUtils.isBlank(examples)) {
            throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_DATA_ERROR,"例句不能为空");
        }

        String[] lines = examples.split("\n");
        if (lines.length % 2 != 0) {
            throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_DATA_ERROR,"例句必须成对出现(英文例句+中文翻译)");
        }

        for (int i = 0; i < lines.length; i += 2) {
            if (StringUtils.isBlank(lines[i])) {
                throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_DATA_ERROR,String.format("第%d个英文例句不能为空", i/2 + 1));
            }
            if (i + 1 >= lines.length || StringUtils.isBlank(lines[i + 1])) {
                throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_DATA_ERROR,String.format("第%d个例句缺少中文翻译", i/2 + 1));
            }
        }
    }
    private void checkBookInfo(String bookInfos) {
        if (StringUtils.isBlank(bookInfos)) {
            throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_DATA_ERROR,"书籍章节信息不能为空");
        }

        String[] parts = bookInfos.split("#");
        if (parts.length < 2) {
            throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_DATA_ERROR,"书籍章节格式应为'书籍名称#章节名称'");
        }

        String bookName = parts[0].trim();
        String chapterName = parts[1].trim();

        // 检查书籍是否存在
        if (vocBookMapper.countByName(bookName) == 0) {
            throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_DATA_ERROR,"书籍'" + bookName + "'不存在");
        }
        // 检查章节是否存在
        else if (vocChapterMapper.countByNameAndBook(chapterName, bookName) == 0) {
            throw new ExcelParseException(ResultCodeEnum.VOC_EXCEL_DATA_ERROR,"章节'" + chapterName + "'在书籍'" + bookName + "'中不存在");
        }
    }
}